package org.springblade.tms.module.tank.importer;

import cn.hutool.core.collection.ListUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springblade.common.utils.EnumUtils;
import org.springblade.common.utils.StreamUtils;
import org.springblade.core.excel.support.ExcelImporter;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.tms.global.enums.CarType;
import org.springblade.tms.global.enums.CargoTypeEnum;
import org.springblade.tms.module.car.base.CarManagementService;
import org.springblade.tms.module.car.dto.CarDto;
import org.springblade.tms.module.car.vo.CarExcelVO;
import org.springblade.tms.module.tank.base.TankService;
import org.springblade.tms.module.tank.entity.TMTankTank;
import org.springblade.tms.module.tank.vo.TankExcelVO;
import org.springblade.tms.module.tank.vo.TankVo;
import org.springblade.tms.module.userinfo.base.DriverManagementService;
import org.springblade.tms.module.userinfo.entity.TMUserInfo;
import org.springframework.data.redis.core.RedisTemplate;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @projectName: BladeX
 * @package: org.springblade.tms.module.supercargoinfo.Importer
 * @className: EscortManagementImporter
 * @author: yr
 * @description: 坦克罐数据导入类
 * @date: 2022/4/22 16:13
 */
@RequiredArgsConstructor
public class TankImporter implements ExcelImporter<TankExcelVO> {
	//服务
	private final TankService service;
	//线程
	private final ThreadPoolExecutor executor;
	//验证器
	private final Validator validator;
	//当前用户
	private final TMUserInfo tMuserInfo;
	//reidsKey
	private final String ImportNo;

	private final RedisTemplate redisTemplate;

	private final BladeUser user;


	@Override
	@SneakyThrows
	public void save(List<TankExcelVO> data) {
		//验证器验证
		List<TankExcelVO> failure = new ArrayList<>();
		data.forEach(tankExcelVO -> {
			Set<ConstraintViolation<TankExcelVO>> validate;
			validate = validator.validate(tankExcelVO);
			if (validate != null && !validate.isEmpty()) {
				failure.add(tankExcelVO);
			}
		});
		//失败条数放入redis
		data.removeAll(failure);
		AtomicLong count = new AtomicLong(failure.size());
		//每500条数据开一个线程
		List<TMTankTank> tmTankTanks = BeanUtil.copy(data, TMTankTank.class);
		List<List<TMTankTank>> split = ListUtil.split(tmTankTanks, 500);
		List<CompletableFuture<Void>> taskList = new ArrayList<>();
		split.forEach(list -> taskList.add(
			CompletableFuture.supplyAsync(() -> {
				list.forEach(tank -> {
					try {
						tank.setTenantId(user.getTenantId());
						tank.setCreateUser(user.getUserId());
						tank.setCreateDept(Long.valueOf(user.getDeptId()));
						R save = service.excelSaveOrUpdate(tank, tMuserInfo);
						if (!save.isSuccess()) {
							count.getAndIncrement();
						}
					} catch (Throwable e) {
						count.getAndIncrement();
					}
				});
				return null;
			}, executor)
		));
		taskList.forEach(StreamUtils.ofConsumer(voidCompletableFuture -> voidCompletableFuture.get()));
		redisTemplate.opsForValue().set(ImportNo, count.longValue());
	}
}
